TalentSync

AI resume builder and ATS optimizer for job seekers. Tailored resumes, outreach, and interview prep from one profile.

Text processing pipeline

Normalizes uploaded resumes into clean text for extraction, ATS, and PDF flows.

Repository layout#

The text processing pipeline spans three primary areas:

  • File upload and routing: FastAPI routes accept uploads and delegate to services.
  • Processing service: Converts file bytes to text/markdown and validates content.
  • LLM-based formatting and analysis: Cleans, normalizes, and extracts structured data from resume text.

Building blocks#

  • File processing and extraction:

  • process_document(file_bytes, file_name): Determines file type and extracts text/markdown using PyMuPDF and pymupdf4llm for PDF/DOC/DOCX, decodes TXT/MD directly, and falls back to a multimodal provider for PDFs when extraction yields empty content.

  • is_valid_resume(text): Validates that the extracted text contains key resume sections using keyword matching.

  • LLM-based cleaning and formatting:

  • build_text_formatter_chain(llm): Creates a LangChain chain that prompts an LLM to clean and normalize raw resume text.

  • format_resume_text_with_llm(raw_text, llm): Executes the chain and returns cleaned text, with fallback to original text on errors.

  • Downstream analysis orchestration:

  • analyze_resume_service(file, llm): Reads file, processes to text, optionally cleans via LLM, validates, converts to JSON via LLM, and performs schema validation.

  • comprehensive_resume_analysis_service(file, llm): Reads file, validates, and runs a detailed analysis LLM chain returning a structured dictionary.

  • format_and_analyze_resume_service(file, llm): Reads file, formats and analyzes via a combined chain, returning cleaned text and analysis.

How it fits together#

The pipeline integrates FastAPI routes, a processing module, and LLM-based formatting and analysis modules. The flow varies slightly depending on whether the caller wants pure text cleaning, JSON extraction, or a detailed analysis.

File upload and routing#

  • The routes expose endpoints for resume analysis, detailed analysis, and a combined format-and-analyze operation. They depend on a request-scoped LLM instance and accept multipart/form-data uploads.

Implementation references:

  • resume_analysis route
  • resume_analysis route
  • resume_analysis route

Document processing workflow#

The process_document function orchestrates extraction across supported formats:

  • TXT/MD: Decoded directly from bytes.
  • PDF/DOC/DOCX: Converted to Markdown using PyMuPDF and pymupdf4llm for consistent parsing.
  • Fallback: For PDFs that yield empty content after initial extraction, a multimodal provider is used to convert the PDF to text.

Text cleaning and normalization#

  • A LangChain prompt builds a chain that asks an LLM to clean and reformat resume text, preserving key information while removing artifacts and improving readability.
  • The chain is executed via format_resume_text_with_llm, which returns the cleaned text or falls back to the original on errors (e.g., rate limits, authentication issues).

Validation logic: is_valid_resume#

The is_valid_resume function checks whether the extracted text contains at least one of several canonical resume keywords. This is a quick filter to reject content that is likely not a resume.

Orchestration services#

  • analyze_resume_service:
  • Reads file bytes, writes a temporary file, processes to text, optionally formats via LLM, validates, converts to JSON via LLM, and performs schema validation.
  • Returns a structured response or raises HTTP exceptions on failure.
  • comprehensive_resume_analysis_service:
  • Reads file, validates, and runs a detailed analysis LLM chain returning a dictionary.
  • format_and_analyze_resume_service:
  • Reads file, formats and analyzes via a combined chain, returning cleaned text and analysis.

Legacy text cleaning utility#

A separate utility exists for cleaning resume text using NLP preprocessing (lemmatization, stopword removal, punctuation stripping). While not used in the current pipeline, it demonstrates normalization techniques.

Dependencies#

External libraries and their roles:

  • PyMuPDF and pymupdf4llm: Core engine for extracting text/markdown from PDF/DOC/DOCX.
  • LangChain: Provides prompt composition and chain execution for LLM-based formatting and analysis.
  • python-dotenv: Used for environment configuration (not directly part of the pipeline but relevant for deployment).

Performance#

  • Extraction efficiency:
  • PyMuPDF and pymupdf4llm are efficient for converting PDF/DOC/DOCX to Markdown. For very large PDFs, consider:
  • Streaming chunks to reduce peak memory usage.
  • Limiting pages or applying OCR pre-processing if needed.
  • LLM calls:
  • LLM-based formatting and analysis are I/O bound; batch requests where possible and avoid redundant formatting for plain TXT/MD.
  • Implement retry/backoff for transient LLM errors.
  • Memory optimization:
  • Avoid storing entire files in memory beyond the minimal window needed for processing.
  • Delete temporary files promptly after processing.
  • Validation cost:
  • Keyword-based validation is O(n) per keyword; keep the keyword list concise and case-insensitive to minimize overhead.

[No sources needed since this section provides general guidance]

Troubleshooting#

Common issues and strategies:

  • Unsupported file type:
  • The processor prints a message and returns None. Ensure the file extension is among supported types.
  • Reference: process_resume.py
  • Corrupted or unreadable files:
  • Exceptions during processing are caught and None is returned. Verify file integrity and permissions.
  • Reference: process_resume.py
  • Empty extraction for PDFs:
  • The processor attempts a fallback conversion using a multimodal provider. Ensure the provider and credentials are configured.
  • Reference: process_resume.py
  • LLM formatting failures:
  • On errors (e.g., rate limits, authentication), the formatter returns the original text. Inspect logs and adjust provider settings.
  • Reference: data_processor.py
  • Validation failures:
  • If is_valid_resume returns False, the service raises an HTTP 400 error. Ensure the file contains recognizable resume content.
  • Reference: resume_analysis.py